package handlers

import (
	"net/http"
	"strconv"

	"minipromgr/internal/models"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// GetItems 获取项目下的所有items
func GetItems(c *gin.Context) {
	projectIDStr := c.Query("project_id")
	itemType := c.Query("type")
	status := c.Query("status")
	priority := c.Query("priority")
	assigneeID := c.Query("assignee_id")

	db := models.GetDB()
	query := db.Model(&models.Item{})

	if projectIDStr != "" {
		projectID, err := strconv.ParseUint(projectIDStr, 10, 32)
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid project_id"})
			return
		}
		query = query.Where("project_id = ?", uint(projectID))
	}

	if itemType != "" {
		query = query.Where("type = ?", itemType)
	}

	if status != "" {
		query = query.Where("status = ?", status)
	}

	if priority != "" {
		query = query.Where("priority = ?", priority)
	}

	if assigneeID != "" {
		query = query.Where("assignee_id = ?", assigneeID)
	}

	var items []models.Item
	if err := query.Preload("Project").Preload("Reporter").Preload("Assignee").Preload("Pictures").Find(&items).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch items"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"items": items})
}

// CreateItem 创建新的item
func CreateItem(c *gin.Context) {
	var item models.Item
	if err := c.ShouldBindJSON(&item); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	db := models.GetDB()
	if err := db.Create(&item).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create item"})
		return
	}

	// 预加载关联数据
	db.Preload("Project").Preload("Reporter").Preload("Assignee").Preload("Pictures").First(&item, item.ID)

	c.JSON(http.StatusCreated, gin.H{"item": item})
}

// GetItem 获取单个item详情
func GetItem(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid item ID"})
		return
	}

	db := models.GetDB()
	var item models.Item
	if err := db.Preload("Project").Preload("Reporter").Preload("Assignee").Preload("Pictures").First(&item, uint(id)).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "Item not found"})
		} else {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch item"})
		}
		return
	}

	c.JSON(http.StatusOK, gin.H{"item": item})
}

// UpdateItem 更新item
func UpdateItem(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid item ID"})
		return
	}

	var updateData models.Item
	if err := c.ShouldBindJSON(&updateData); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	db := models.GetDB()
	var item models.Item
	if err := db.First(&item, uint(id)).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "Item not found"})
		} else {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch item"})
		}
		return
	}

	if err := db.Model(&item).Updates(updateData).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update item"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"item": item})
}

// DeleteItem 删除item
func DeleteItem(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid item ID"})
		return
	}

	db := models.GetDB()
	if err := db.Delete(&models.Item{}, uint(id)).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete item"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Item deleted successfully"})
}

// AssociateImagesWithItem 将图片关联到Item
func AssociateImagesWithItem(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid item ID"})
		return
	}

	var request struct {
		Filenames []string `json:"filenames" binding:"required"`
	}

	if err := c.ShouldBindJSON(&request); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	db := models.GetDB()
	
	// 更新图片的item_id
	for _, filename := range request.Filenames {
		if err := db.Model(&models.Picture{}).Where("filename = ?", filename).Update("item_id", uint(id)).Error; err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to associate image with item"})
			return
		}
	}

	c.JSON(http.StatusOK, gin.H{"message": "Images associated with item successfully"})
}
